package tcakes.ccrefactoring;
import junit.framework.TestCase;

public class ArgsTest extends TestCase {
    public void testCreateWithNoSchemaOrArguments() throws Exception {
        Args args = new Args("", new String[0]);
        assertEquals(0, args.cardinality());
    }

    public void testWithNoSchemaButWithOneArgument() throws Exception {
        try {
            new Args("", new String[]{"-x"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.UNEXPECTED_ARGUMENT, e.getErrorCode());
            assertEquals('x', e.getErrorArgumentId());
        }
    }

    public void testWithNoSchemaButWithMultipleArguments() throws Exception {
        try {
            new Args("", new String[]{"-x","-y"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.UNEXPECTED_ARGUMENT, e.getErrorCode());
            assertEquals('x',e.getErrorArgumentId());
        }
    }

    public void testNonLetterSchema() throws Exception {
        try {
            new Args("*", new String[]{});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.INVALID_ARGUMENT_NAME, e.getErrorCode());
            assertEquals('*',e.getErrorArgumentId());
        }
    }

    public void testInvalidArgumentFormat() throws Exception {
        try {
            new Args("f-", new String[]{});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.INVALID_FORMAT, e.getErrorCode());
            assertEquals('f', e.getErrorArgumentId());
        }
    }

    public void testSimpleBooleanPresent() throws Exception {
        Args args = new Args("x", new String[]{"-x"});
        assertEquals(1,args.cardinality());
        assertEquals(true,args.getBoolean('x'));
        assertEquals(false,args.getBoolean('y'));
    }

    public void testSimpleStringPresent() throws Exception {
        Args args = new Args("x*", new String[]{"-x", "param"});
        assertEquals(1,args.cardinality());
        assertTrue(args.has('x'));
        assertEquals("param",args.getString('x'));
        assertEquals("",args.getString('y'));
    }

    public void testMissingStringArgument() throws Exception {
        try {
            new Args("x*", new String[]{"-x"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.MISSING_STRING, e.getErrorCode());
            assertEquals('x', e.getErrorArgumentId());
        }
    }

    public void testSpacesInFormat () throws Exception {
        Args args = new Args("x, y", new String[]{"-xy"});
        assertEquals(2,args.cardinality());
        assertTrue(args.has('x'));
        assertTrue(args.has('y'));
    }

    public void testSimpleIntPresent() throws Exception {
        Args args = new Args("x#", new String[]{"-x", "42"});
        assertEquals(1,args.cardinality());
        assertTrue(args.has('x'));
        assertEquals(42,args.getInt('x'));
        assertEquals(0,args.getInt('y'));
    }

    public void testInvalidInteger() throws Exception {
        try {
            new Args("x#", new String[]{"-x", "Forty two"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.INVALID_INTEGER, e.getErrorCode());
            assertEquals('x', e.getErrorArgumentId());
            assertEquals("Forty two", e.getErrorParameter());
        }
    }

    public void testMissingInteger() throws Exception {
        try {
            new Args("x#", new String[]{"-x"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.MISSING_INTEGER, e.getErrorCode());
            assertEquals('x', e.getErrorArgumentId());
        }
    }

    public void testSimpleDoublePresent() throws Exception {
        Args args = new Args("x##", new String[]{"-x", "42.3"});
        assertEquals(1,args.cardinality());
        assertTrue(args.has('x'));
        assertEquals(42.3, args.getDouble('x'), .001);
    }

    public void testInvalidDouble() throws Exception {
        try {
            new Args("x##", new String[]{"-x", "Forty two"});
            fail();
        } catch(ArgsException e) {
            assertEquals(ArgsException.ErrorCode.INVALID_DOUBLE, e.getErrorCode());
            assertEquals('x', e.getErrorArgumentId());
            assertEquals("Forty two", e.getErrorParameter());
        }
    }

    public void testMissingDouble() throws Exception {
        try {
            new Args("x##", new String[]{"-x"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.MISSING_DOUBLE,e.getErrorCode());
            assertEquals('x',e.getErrorArgumentId());
        }
    }

    public void testStringArrayPresent1() throws Exception {
        Args args = new Args("x[*],d", new String[]{"-x", "42.3", "arrayArg1", "-d"});
        assertEquals(2,args.cardinality());
        assertTrue(args.has('x'));
        assertTrue(args.has('d'));
        assertEquals(true,args.getBoolean('d'));
        assertEquals("42.3",args.getStringArray('x')[0]);
        assertEquals("arrayArg1",args.getStringArray('x')[1]);
    }

    public void testStringArrayPresent2() throws Exception {
        Args args = new Args("x[*]", new String[]{"-x", "42.3", "arrayArg1"});
        assertEquals(1,args.cardinality());
        assertTrue(args.has('x'));
        assertEquals("42.3",args.getStringArray('x')[0]);
        assertEquals("arrayArg1",args.getStringArray('x')[1]);
    }

    public void testMissingStringArray1() throws Exception {
        try {
            new Args("x[*],d", new String[]{"-x", "-d"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.MISSING_STRING_ARRAY, e.getErrorCode());
            assertEquals('x',e.getErrorArgumentId());
        }
    }

    public void testMissingStringArray2() throws Exception {
        try {
            new Args("x[*]", new String[]{"-x"});
            fail();
        } catch (ArgsException e) {
            assertEquals(ArgsException.ErrorCode.MISSING_STRING_ARRAY, e.getErrorCode());
            assertEquals('x',e.getErrorArgumentId());
        }
    }

}
